package com.mugui.spring.util;

import java.time.Duration;
import java.util.HashMap;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisConnectionUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import com.mugui.MuguiApplication;
import com.mugui.util.Other;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * redis工具类
 * 
 * @author Administrator
 *
 */
@Component
public class RedisAccess {

	private String REDISTHOST = null;
	private int REDISPORT;
	private String REDISPASSWORD = null;

	private StringRedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
		StringRedisTemplate template = new StringRedisTemplate();
		template.setConnectionFactory(redisConnectionFactory);
		template.afterPropertiesSet();
		return template;
	}

	@Autowired
	private Environment env;

	public RedisConnectionFactory createRedisFactory(int select) {
		if (StringUtils.isBlank(REDISTHOST)) {
			REDISTHOST = env.getProperty("spring.redis.host");
			REDISPORT = Integer.parseInt(env.getProperty("spring.redis.port"));
			REDISPASSWORD = env.getProperty("spring.redis.password");
		}
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxTotal(20);
		poolConfig.setMaxIdle(20);
		poolConfig.setMaxWaitMillis(10000);
		poolConfig.setMinIdle(10);
		poolConfig.setTestOnBorrow(true);
		poolConfig.setTestOnReturn(false);
		poolConfig.setTimeBetweenEvictionRunsMillis(10000);
		poolConfig.setTestOnCreate(true);
		poolConfig.setMinEvictableIdleTimeMillis(5000);
		poolConfig.setTestWhileIdle(true);
		JedisClientConfiguration clientConfig = JedisClientConfiguration.builder().usePooling().poolConfig(poolConfig)
				.and().readTimeout(Duration.ofMillis(10000)).build();

		// 单点redis
		RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();

		redisConfig.setHostName(REDISTHOST);
		if (StringUtils.isNotBlank(REDISPASSWORD)) {
			redisConfig.setPassword(RedisPassword.of(REDISPASSWORD));
		}
		redisConfig.setPort(REDISPORT);
		redisConfig.setDatabase(select);
		return new JedisConnectionFactory(redisConfig, clientConfig);
	}

	public StringRedisTemplate getRedisClient() {
		return getRedisClient(0);
	}

	public static ThreadLocal<HashMap<Integer, StringRedisTemplate>> threadlocal = new ThreadLocal<>();

	public StringRedisTemplate getRedisClient(int i) {

		HashMap<Integer, StringRedisTemplate> hashMap = threadlocal.get();
		if (hashMap == null) {
			synchronized (threadlocal) {
				hashMap = threadlocal.get();
				if (hashMap == null)
					threadlocal.set(hashMap = new HashMap<>());
			}
		}
		StringRedisTemplate stringRedisTemplate = hashMap.get(i);
		if (stringRedisTemplate != null) {
			try {
				stringRedisTemplate.opsForValue().get("mugui=StringRedisTemplate");
			} catch (Exception e) {
				stringRedisTemplate = null;
				hashMap.remove(i);
			}
		}
		if (stringRedisTemplate == null) {
			RedisConnectionFactory createRedisFactory = createRedisFactory(i);
			while (true) {
				try {
					stringRedisTemplate = redisTemplate(createRedisFactory);
					stringRedisTemplate.getConnectionFactory().getConnection().time();
					hashMap.put(i, stringRedisTemplate);
					break;
				} catch (Exception e) {
					e.printStackTrace();
					Other.sleep(5000);
				}
			}
		}

		return stringRedisTemplate;
	}

	public void push(String key, String bean) {
		StringRedisTemplate jedis = null;
		jedis = getRedisClient();
		jedis.opsForList().rightPush(key, bean.toString());
	}

	public String pop(String key) {
		StringRedisTemplate jedis = null;
		jedis = getRedisClient();
		return jedis.opsForList().leftPop(key);
	}

	public String get(String key) {
		StringRedisTemplate jedis = null;
		jedis = getRedisClient();
		return jedis.opsForValue().get(key);
	}

	public void set(String key, String bean) {
		StringRedisTemplate jedis = null;
		jedis = getRedisClient();
		jedis.opsForValue().set(key, bean);
	}

	public void del(String key) {

	}
}
